package com.bootdo.system.controller;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.bootdo.common.controller.BaseController;
import com.bootdo.common.domain.SysDictDO;
import com.bootdo.common.service.SysDictService;
import com.bootdo.common.utils.PageUtils;
import com.bootdo.common.utils.Query;
import com.bootdo.common.utils.R;
import com.bootdo.system.domain.Course;
import com.bootdo.system.domain.CourseTime;
import com.bootdo.system.domain.Customer;
import com.bootdo.system.domain.Order;
import com.bootdo.system.domain.Parents;
import com.bootdo.system.domain.RedBag;
import com.bootdo.system.domain.UserAccount;
import com.bootdo.system.domain.UserAccountDetail;
import com.bootdo.system.domain.VeriCode;
import com.bootdo.system.service.CourseService;
import com.bootdo.system.service.CourseTimeService;
import com.bootdo.system.service.CustomerService;
import com.bootdo.system.service.OrderService;
import com.bootdo.system.service.RedBagConfigService;
import com.bootdo.system.service.RedBagService;
import com.bootdo.system.service.ShareRecordService;
import com.bootdo.system.service.UserAccountDetailService;
import com.bootdo.system.service.UserAccountService;
import com.bootdo.system.service.VeriCodeService;
import com.bootdo.system.util.GetWxOrderno;
import com.bootdo.system.util.LocationUtil;
import com.bootdo.system.util.RequestHandler;
import com.github.pagehelper.PageInfo;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@RequestMapping("/sys/order")
@Controller
@Api(value = "/sys/order", description = "订单操作接口")
public class OrderController extends BaseController {
	@Autowired
	OrderService service;
	
	@Autowired
	SysDictService sysDictService;
	
	@Autowired
	UserAccountService userAccountService;
	
	@Autowired
	CourseTimeService courseTimeService;
	
	@Autowired
	CourseService courseService;
	
	@Autowired
	CustomerService customerService;
	
	@Autowired
	UserAccountDetailService userAccountDetailService;
	@Autowired
	RedBagConfigService redBagConfigService;
	
	@Autowired
	RedBagService redBagService;
	
	@Autowired
	VeriCodeService veriCodeService;
	
	@Autowired
	ShareRecordService shareRecordService;
	
	

	@ApiOperation(value="订单查询", notes="根据条件查询订单", response=String.class)
	@ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "订单id", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "courseId", value = "课程id", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "orderStatus", value = "订单状态", required = false,paramType="query", dataType = "int"),
        @ApiImplicitParam(name = "orderNo", value = "订单编号", required = false,paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "parentsId", value = "所属用户id", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "babyId", value = "所属宝宝id", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "customerId", value = "商户id", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "lng", value = "经度值", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "lat", value = "纬度值", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true,paramType="query", dataType = "int"),
        @ApiImplicitParam(name = "pageNum", value = "当前页数", required = true,paramType="query", dataType = "int")
	})
	@GetMapping("/list")
	@ResponseBody
	R list(@RequestParam Map<String,Object> param)  throws Exception{
		 Query query = new Query(param);
		 Double lng =null;
		 if(param.get("lng") != null) {
			 lng = Double.parseDouble(param.get("lng") + "");
		 }
		 Double lat = null;
		 if(param.get("lat") != null) {
			 lat = Double.parseDouble(param.get("lat") + "");
		 }
		List<Order> orderList = service.list(query);
		for(Order order:orderList) {
			CourseTime courseTime = courseTimeService.get(order.getCourseId());
			if(courseTime != null) {
				order.setCourseTime(courseTime);
				Course c = courseService.get(courseTime.getCourseId());
				if(c == null) {
					continue;
				}
				if(c.getCourseOwner() != null) {
					Customer cust = customerService.get(Long.parseLong(c.getCourseOwner()+""));
					order.setCustomer(cust);
					if(lng != null && lat != null && cust != null) {
						Double lng2 = cust.getLongitude();
						Double lat2 = cust.getLatitude();
						if(lng2 != null && lat2 != null) {
							c.setDistance( LocationUtil.getDistance(lat, lng, lat2, lng2));
						}else {
							c.setDistance("0");
						}
					}else {
						c.setDistance("0");
					}
				}else {
					c.setDistance("0");
				}
				order.setCourse(c);
			}else {
				order.setCourseTime(null);
				order.setCourse(null);
			}
		}
		PageInfo<Order> pageInfo = new PageInfo<Order>(orderList);
		int total = (int)pageInfo.getTotal();
		PageUtils pageUtil = new PageUtils(orderList, total);
		return new R("obj",pageUtil);
	}

	@ApiOperation(value="以往和已定订单查询", notes="根据条件查询订单", response=String.class)
	@ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "订单id", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "courseId", value = "课程id", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "orderStatus", value = "订单状态", required = false,paramType="query", dataType = "Integer"),
        @ApiImplicitParam(name = "orderNo", value = "订单编号", required = false,paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "parentsId", value = "所属用户id", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "babyId", value = "所属宝宝id", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "customerId", value = "商户id", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "isOver", value = "1为以往 0为已定", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "lng", value = "经度值", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "lat", value = "纬度值", required = false,paramType="query", dataType = "Long"),
        @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true,paramType="query", dataType = "Integer"),
        @ApiImplicitParam(name = "pageNum", value = "当前页数", required = true,paramType="query", dataType = "Integer")
	})
	@GetMapping("/listByTime")
	@ResponseBody
	R listByTime(@RequestParam Map<String,Object> param)  throws Exception{
		Query query = new Query(param);
		List<Order> orderList = service.listByTime(query);
		Double lng = null;
		if(param.containsKey("lng")) {
			lng = Double.parseDouble(param.get("lng") + "");
		}
		Double lat = null;
		if(param.containsKey("lat")) {
			lat = Double.parseDouble(param.get("lat") + "");
		}
		for(Order order:orderList) {
			CourseTime courseTime = courseTimeService.get(order.getCourseId());
			if(courseTime != null) {
				order.setCourseTime(courseTime);
				Course c = courseService.get(courseTime.getCourseId());
				if(c != null && c.getCourseOwner() != null) {
					Customer cust = customerService.get(Long.parseLong(c.getCourseOwner()+""));
					order.setCustomer(cust);
					if(lng != null && lat != null && cust != null) {
						Double lng2 = cust.getLongitude();
						Double lat2 = cust.getLatitude();
						if(lng2 != null && lat2 != null) {
							c.setDistance( LocationUtil.getDistance(lat, lng, lat2, lng2));
						}else {
							c.setDistance("0");
						}
					}else {
						c.setDistance("0");
					}
				}
				order.setCourse(c);
			}
		}
		PageInfo<Order> pageInfo = new PageInfo<Order>(orderList);
		int total = (int)pageInfo.getTotal();
		PageUtils pageUtil = new PageUtils(orderList, total);
		return new R("obj",pageUtil);
	}
	
	@ApiOperation(value="订单详情", notes="根据条件查询订单", response=String.class)
	@ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "订单id", required = true,paramType="query", dataType = "Long"),
	})
	@GetMapping("/edit")
	@ResponseBody
	R edit( Long id)  throws Exception{
		return new R("obj",service.get(id));
	}

	@ApiOperation(value="订单保存", notes="保存订单", response=String.class)
	@PostMapping("/save")
	@ResponseBody
	R save(@RequestBody Order order) throws ParseException {
		
		VeriCode vc = veriCodeService.getByPhone(order.getParentPhone());
		if(vc == null) {
			return R.error("验证码不存在");
		}
		if(!order.getPhoneCode().equals(vc.getCode())) {
			return R.error("验证码不正确");
		}
		Map<String,Object> codeMap = new HashMap<String,Object>();
		codeMap.put("type", "codePeriod");
		SysDictDO codeDict =  sysDictService.list(codeMap).get(0);
		if((new Date().getTime()-vc.getCreateTime().getTime()) > Integer.parseInt(codeDict.getValue())*60000) {
			return R.error("验证码已经过期，请重新获取验证码");
		}
		veriCodeService.removeByPhone(order.getParentPhone());
		
		CourseTime courseTime = courseTimeService.get(order.getCourseId());
		if(courseTime == null) {
			return R.error("课程不存在");
		}
		Course course = courseService.get(courseTime.getCourseId());
		if(course == null) {
			return R.error("课程不存在");
		}
		int remainPersons = courseTime.getRemainderNumber();
		if(remainPersons<1) {
			return R.error("课程已经报满");
		}
		String startTime = courseTime.getStartTime();
		if(startTime != null && startTime.length()==16) {
			startTime = startTime + ":00";
		}
		SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = new Date();
		if(date.getTime() < fmt.parse(startTime).getTime()) {
			return R.error("报名未开始");
		}
		SysDictDO dict = sysDictService.getSingleDictByType("liudian");
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		String formatStr =formatter.format(new Date()) + (int)((Math.random()*9+1)*100000);
		order.setOrderNo(formatStr);
		order.setOrderStatus(0L);
		order.setCreateTime(new Date());
		order.setCustomerId(course.getCourseOwner());
		order.setCoursePrice(Integer.parseInt(dict.getValue())*order.getCoursePoints());
		if (service.save(order) > 0) {
			courseTime.setRemainderNumber(remainPersons - 1);
			courseTime.setSignedNumber(courseTime.getSignedNumber() + 1);
			if(remainPersons == 1) {
				courseTime.setCourseStatus("2");
			}else {
				courseTime.setCourseStatus("1");
			}
			courseTimeService.update(courseTime);
			return R.saveOk(order.getId().toString());
		} else {
			return R.error(1, "保存失败");
		}
	}

	@ApiOperation(value="订单更新", notes="更新订单", response=String.class)
	@PostMapping("/update")
	@ResponseBody
	R update(@RequestBody Order order)  throws Exception{
		SysDictDO dict = sysDictService.getSingleDictByType("liudian");
		order.setCoursePrice(Integer.parseInt(dict.getValue())*order.getCoursePoints());
		if (service.update(order) > 0) {
			return R.ok();
		} else {
			return R.error(1, "更新失败");
		}
	}

	@ApiOperation(value="订单删除", notes="根据订单id删除", response=String.class)
	@ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "订单id", required = true, paramType="query", dataType = "Long"),
	})
	@GetMapping("/remove")
	@ResponseBody
	R remove(Long id)  throws Exception{
		if (service.remove(id) > 0) {
			return R.ok();
		} else {
			return R.error(1, "删除失败");
		}
	}
	
	@ApiOperation(value="订单退款", notes="根据订单id退款", response=String.class)
	@ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "订单id", required = true, paramType="query", dataType = "Long"),
	})
	@GetMapping("/drawBack")
	@ResponseBody
	R drawBack(Long id)  throws Exception{
		Order order = service.get(id);
		if(order != null) {
			if(order.getOrderStatus() != 1) {
				return R.error(1, "订单状态不是已支付");
			}
			Long accountTotal = order.getAccountTotal();
				UserAccount ua = userAccountService.getByUserId(order.getParentsId());
				ua.setPoint(ua.getPoint() + accountTotal);
				userAccountService.update(ua);
				UserAccountDetail uad = new UserAccountDetail();
				uad.setDealTime(new Date());
				uad.setDealType("收入");
				uad.setPoint(accountTotal);
				uad.setUserId(order.getParentsId());
				uad.setOrderId(order.getId());
				userAccountDetailService.save(uad);
			order.setOrderStatus(-1L);
			if (service.update(order) > 0) {
				return R.ok();
			} else {
				return R.error(1, "退款失败");
			}
		}else {
			return R.error(1, "订单不存在");
		}
	}
	
	@ApiOperation(value="订单取消", notes="根据订单id取消订单", response=String.class)
	@ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "订单id", required = true, paramType="query", dataType = "Long"),
	})
	@GetMapping("/orderCancel")
	@ResponseBody
	R orderCancel(Long id)  throws Exception{
		int result = service.cancelOrder(id);
		if(result >0){
			return R.ok();
		} else if (result == 0){
				return R.error(1, "订单取消失败");
		}else if (result == -1) {
			return R.error(1, "订单不存在");
		}else {
			return R.error(1, "订单取消失败");
		}
	}
	
	@ApiOperation(value="订单核销", notes="根据订单id核销订单", response=String.class)
	@ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "订单id", required = true, paramType="query", dataType = "Long"),
	})
	@GetMapping("/orderWriteOff")
	@ResponseBody
	R orderWriteOff(Long id)  throws Exception{
		int result = service.updateOrderStatus(id,3L);
		if(result >0){
			return R.ok();
		} else if (result == 0){
				return R.error(1, "订单核销失败");
		}else if (result == -1) {
			return R.error(1, "订单不存在");
		}else {
			return R.error(1, "订单核销失败");
		}
	}
	
	
	
		@ApiOperation(value="订单支付成功接口", notes="订单支付成功后的回调接口", response=String.class)
		@ApiImplicitParams({
	        @ApiImplicitParam(name = "id", value = "订单id", required = true, paramType="query", dataType = "Long"),
	        @ApiImplicitParam(name = "redBagId", value = "使用的红包id", required = false, paramType="query", dataType = "Long"),
	        @ApiImplicitParam(name = "payType", value = "支付类型 0余额 1微信", required = true, paramType="query", dataType = "Long"),
	        @ApiImplicitParam(name = "payTotal", value = "支付金额", required = true, paramType="query", dataType = "Long")
		})
		@GetMapping(value = "/paySuccess")   
		@ResponseBody public R notify(@RequestParam Map<String,Object> param) throws Exception{  
			System.out.println("=========id=" + param.get("id") +",redBagId==" + param.get("redBagId")  + ",payType=" + param.get("payType") + ",payTotal=" + param.get("payTotal"));
			Long id = Long.parseLong(param.get("id")+"");
			Long redBagId = null;
			if(param.get("redBagId") != null && !"null".equals(param.get("redBagId") +"")) {
				redBagId =  Long.parseLong(param.get("redBagId")+"");
			}
			int payType = Integer.parseInt(param.get("payType") + "");
			Long payTotal = Long.parseLong(param.get("payTotal")+"");
			Order order=service.get(id); 
		    if(order == null) {
		    	return R.error(1, "订单不存在");
		    }
		    
           if(order.getOrderStatus()==0){  
            	if(redBagId != null) {
            		//如果使用了红包，则支付成功后，将该红包从表里删除
            		RedBag rb = redBagService.get(redBagId);
            		rb.setBagStatus(1);
            		redBagService.update(rb);
            		order.setRedBagId(redBagId);
            	}
            	if(payTotal!= null && payTotal>0 && payType == 0) {
            		order.setAccountTotal(payTotal);
            		//如果使用了账户中的遛点，则支付成功后，从账户中扣除相应的遛点
            		UserAccount ua = userAccountService.getByUserId(order.getParentsId());
            		if(ua == null) {
            			return R.error("该用户还没有账户信息");
            		}
            		if((ua.getPoint() - payTotal)<0) {
            			return R.error("用户账户余额不足");
            		}
            		ua.setPoint(ua.getPoint() - payTotal);
            		userAccountService.update(ua);
            		UserAccountDetail uad = new UserAccountDetail();
            		uad.setDealTime(new Date());
            		uad.setDealType("支出");
            		uad.setPoint(payTotal);
            		uad.setUserId(order.getParentsId());
            		uad.setOrderId(order.getId());
            		userAccountDetailService.save(uad);
            	}
            	order.setPayTime(new Date());
            	order.setPayType(payType);
            	order.setOrderStatus(1L);
            	service.update(order);
               return R.ok();
            }else {
            	 return R.error(1, "订单已支付");  
            }
	}  
		
}
